home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power Programmierung
/
Power-Programmierung (Tewi)(1994).iso
/
magazine
/
drdobbs
/
1988
/
07
/
c_chest
/
c_chest.lst
Wrap
File List
|
1988-04-25
|
12KB
|
394 lines
Listing 1 -- shellarc.c, Printed 4/24/1988
________________________________________________________________
1| #include <stdio.h>
2| #include <ctype.h>
3| #include <tools/getargs.h>
4|
5| /*------------------------------------------------------------
6| * SHELLARC.C This program manufactures a shell archive.
7| * Usage is:
8| * shellarc [-ffile] [-q] names...
9| *
10| * if -f is specified, the rest of the command line is ignored
11| * and file names are taken from the indicated file, otherwise
12| * filenames are taken from the command line.
13| * The output archive looks like this:
14| *
15| * cat >file <<"END-OF-FILE--END-OF-FILE--END-OF-FILE"
16| * <contents of file>
17| * "END-OF-FILE--END-OF-FILE--END-OF-FILE"
18| *
19| * Lines (or command-line arguments) that start with a = are
20| * written to the output file in the corresponding place.
21| * For example, the list:
22| *
23| * file1
24| * = mkdir foo
25| * foo/file2
26| *
27| * comes out as follows:
28| *
29| * cat >file1 <<"END-OF-FILE--END-OF-FILE--END-OF-FILE"
30| * <contents of file1>
31| * "END-OF-FILE--END-OF-FILE--END-OF-FILE"
32| * mkdir foo
33| * cat >foo/file2 <<"END-OF-FILE--END-OF-FILE--END-OF-FILE"
34| * <contents of foo/file2>
35| * "END-OF-FILE--END-OF-FILE--END-OF-FILE"
36| *
37| * The = sign and any trailing whitespaces is removed.
38| *
39| * If -q is specified, the quotes are omitted from the
40| * END-OF-FILE... In this case the shell will expand shell
41| * varaibles, etc, that are present in the file.
42| *------------------------------------------------------------
43| */
44|
45| char **Argv = NULL ;
46| int Argc = 0 ;
47| FILE *Fd = NULL ;
48| int Noquote = 0 ;
49| void get_file();
50| int Dodot = 0;
51|
52| #define NOQUOTE_MARK "END-OF-FILE--END-OF-FILE--END-OF-FILE"
53| #define NORM_MARK "\"END-OF-FILE--END-OF-FILE--END-OF-FILE\""
54| #define BUFSIZE 1024
55|
56| ARG Argtab[] =
57| {
58| {'f',PROC, (int *)get_file,"Use <str> as command file" },
59| {'q',BOOLEAN,&Noquote, "Expand shell vars on dearchiving" },
60| {'.',BOOLEAN,&Dodot, "precede all file names with a dot"}
61| };
62|
63| static char *Usage_msg[] =
64| {
65| "",
66| "Shellarc makes a shell archive by concatenating together the",
67| "files listed on the command line (or in the command file) with",
68| "interspersed shell directives so that, when the output file is",
69| "run, it will unpack itself. For example, shellarc \"=mkdir test\"",
70| "test/file1 test/file2 sends the following to standard output:",
71| "",
72| "\tmkdir test",
73| "\tcat >test/file1 <<\"END-OF-FILE--END-OF-FILE--END-OF-FILE\"",
74| "\t<contents of test/file1>",
75| "\t\"END-OF-FILE--END-OF-FILE--END-OF-FILE\"",
76| "\tcat >test/file2 <<\"END-OF-FILE--END-OF-FILE--END-OF-FILE\"",
77| "\t<contents of test/file2>",
78| "\t\"END-OF-FILE--END-OF-FILE--END-OF-FILE\"",
79| "",
80| "Arguments that begin with = are just written to the output",
81| "file in the place coresponding to the position on the command",
82| "line (with the = stripped. -q removes the quotes from the",
83| "END-OF-FILE... string. -f causes commands to be taken from the",
84| "file instead of the command line, one file name or = command",
85| "per line",
86| NULL
87| };
88|
89| /*------------------------------------------------------------*/
90|
91| usage()
92| {
93| char **p;
94| for( p = Usage_msg; *p; puts(*p++) )
95| ;
96|
97| exit( 1 );
98| }
99|
100| /*------------------------------------------------------------*/
101|
102| void get_file( name )
103| char *name;
104| {
105| /* Open a file and exit if you can't */
106|
107| if( !(Fd = fopen(name,"r") ))
108| {
109| perror( name );
110| exit( 1 );
111| }
112| }
113|
114| /*------------------------------------------------------------*/
115|
116| char *nextline( buf, n )
117| char *buf;
118| {
119| /* Get the next input line of the description file. Get the
120| * line either from a file specified with -f on the command
121| * line (if Fd is NULL), or from the command line itself (if
122| * it's not). Return NULL at ten of file, the buf argument
123| * otherwise.
124| */
125|
126| char *rval;
127|
128| if( Fd )
129| {
130| if( rval = fgets( buf, n, Fd ) )
131| buf[ strlen(buf) - 1 ] = '\0' ; /* Overwrite \n */
132|
133| return rval;
134| }
135| else if( --Argc )
136| {
137| strncpy( buf, *++Argv, n );
138| return buf;
139| }
140| else
141| return NULL;
142| }
143|
144| /*------------------------------------------------------------*/
145|
146| main( argc, argv )
147| char **argv;
148| {
149| char *mark = NORM_MARK ;
150| FILE *ifile;
151| static char buf[ BUFSIZE ];
152| char *p;
153| char *dot = "";
154|
155| reargv( &argc, &argv );
156|
157| Argc = getargs( argc, argv, Argtab,
158| sizeof(Argtab)/sizeof(ARG), usage );
159| Argv = argv;
160|
161| if( Noquote )
162| mark = NOQUOTE_MARK ;
163|
164| if( Dodot )
165| dot = "." ;
166|
167| printf("#\n"); /* Make this a C-shell script */
168|
169| while( nextline( buf, BUFSIZE ) )
170| {
171| if( *buf == '=' )
172| {
173| for(p = buf + 1; isspace( *p ) ; ++p )
174| ;
175| puts( p );
176| }
177| else
178| {
179| if( !(ifile = fopen(buf, "r")) )
180| perror( buf );
181| else
182| {
183| fprintf( stderr, "%s:\n", buf );
184| printf ("echo Unarchiving %s%s\n", dot, buf );
185| printf ("cat >%s%s <<%s\n", dot, buf, mark );
186|
187| while( fgets(buf, BUFSIZE, ifile) )
188| fputs( buf, stdout );
189|
190| fclose( ifile );
191| puts( mark );
192| }
193| }
194| }
195| }
Listing 2 -- exp-arc.c, Printed 4/24/1988
________________________________________________________________
1| #include <stdio.h>
2| #include <stdlib.h>
3| #include <ctype.h>
4| #include <io.h> /* prototype for mktemp() */
5|
6| #define MAXARRAY 256 /* Maximum input line size */
7| #define REDIR 0 /* return value from extract_stuff() */
8| #define NOREDIR 1 /* " */
9|
10| /*------------------------------------------------------------*/
11|
12| char *do_input( word, echo, tname, inp )
13| char *word; /* Terminal string */
14| int echo; /* echo file to stdout if true */
15| FILE *inp; /* input stream */
16| {
17| /* Read lines from "inp" up to "word" into a temporary
18| * file, then close the temporary file, and return its name.
19| */
20|
21| char *temp_name;
22| static char template[ 16 ];
23|
24| FILE *tfile; /* FILE pointer to temporary file */
25| char buf[256]; /* Input line buffer. */
26|
27| strcpy(template,"eaXXXXXX");
28| if( (temp_name = mktemp(template)) == NULL )
29| {
30| fprintf(stderr,"Can't make temporary file name\n");
31| exit(1);
32| }
33|
34| if( !(tfile = fopen( temp_name, "w" )) )
35| {
36| perror( temp_name );
37| exit(1);
38| }
39|
40| while( fgets(buf, sizeof(buf), inp) )
41| {
42| if( strcmp(buf, word) == 0 )
43| break;
44|
45| if( echo )
46| fprintf( stderr, "<< %s", buf );
47|
48| fputs( buf, tfile );
49| }
50|
51| fclose( tfile );
52| return temp_name ;
53| }
54|
55| /*------------------------------------------------------------*/
56|
57| usage()
58| {
59| fprintf(stderr, "Usage: exp-arc [-e] archive...\n\n");
60| fprintf(stderr, "Expand a UNIX shell archive.\n");
61| fprintf(stderr, "-e to print expanded files to stderr\n");
62| exit( 1 );
63| }
64|
65| /*------------------------------------------------------------*/
66|
67| main( argc, argv )
68| char **argv;
69| {
70| /* Usage: exp-arc [-e] archive_file...
71| *
72| * Expand a UNIX shell archive.
73| * -e to print files to standard error as they're expanded
74| */
75|
76| int echo = 0;
77| int i;
78| char *temp_name;
79| FILE *archive;
80| char *word;
81| static char command[ MAXARRAY ];
82|
83| ++argv;
84| --argc;
85|
86| if( argc && argv[0][0] == '-' )
87| {
88| if( argv[0][1] == 'e' )
89| echo = 1;
90| else
91| usage();
92|
93| --argc ;
94| ++argv ;
95| }
96|
97| if( argc == 0 )
98| usage();
99|
100| for( ; --argc >= 0; ++argv )
101| {
102| if( !(archive = fopen(*argv, "r")) )
103| {
104| perror( *argv );
105| exit(1);
106| }
107|
108| while((i = extract_stuff(command,&word,archive)) != EOF)
109| {
110| if( i == NOREDIR )
111| system( command );
112| else
113| {
114| temp_name=do_input(word,echo,temp_name,archive);
115|
116| if( !freopen( temp_name, "r", stdin ) )
117| {
118| perror( temp_name );
119| exit(1);
120| }
121|
122| system( command );
123|
124| freopen( "con:", "r", stdin );
125| unlink ( temp_name );
126| }
127| }
128|
129| fclose( archive );
130| }
131| }
132|
133| /*------------------------------------------------------------*/
134|
135| int extract_stuff( command, word, inp )
136| char *command;
137| char **word;
138| FILE *inp;
139| {
140| /* Read a line of input. If it takes the form:
141| *
142| * cat >file <<pattern
143| *
144| * put everything up to the << into "command."
145| * Modify *word to point at word. That is,
146| * given the previous line, command will
147| * hold "cat >file" and word will hold
148| * "pattern". The space to the right of
149| * the 'e' in file will be replaced with a
150| * '\0'. Return REDIR in this case.
151| * If the "cat," the >, or the << is
152| * missing, put the entire line into command
153| * and return NOREDIR. Return EOF at end of
154| * file.
155| */
156|
157| char *p, *endp;
158|
159| if( ! fgets(command,MAXARRAY,inp) )
160| return EOF;
161|
162| for( p = command; isspace(*p) ; ++p )
163| ;
164|
165| if( !(p[0]=='c' && p[1]=='a' && p[2]=='t' ) )
166| return NOREDIR;
167|
168| for( p += 3; isspace(*p) ; ++p )
169| ;
170|
171| if( p[0] != '>' )
172| return NOREDIR;
173|
174| for( ++p; isspace(*p); ++p )
175| ;
176|
177| while( *p && !isspace(*p) )
178| ++p;
179| endp = p; /* Just remember it for now */
180|
181| for(; isspace(*p); ++p )
182| ;
183|
184| if( !(p[0]=='<' && p[1]=='<') )
185| return NOREDIR;
186|
187| for( p += 2 ; isspace(*p); ++p )
188| ;
189|
190| *endp = '\0'; /* Now terminate it */
191| *word = p ;
192| return REDIR;
193| }